import java.util.ArrayList;
import java.util.List;

/**
 * @modulename Loader
 * @description This class represents the pass two of the Linker/Loader.
 * Affectionately called the Loader, as it handles loading memory of the 
 * combined programs
 * @callsequence The Loader is a static class, so each call to a Loader class will adjust
 * the overall Loader representation.
 * @inparam none
 * @outparam none
 * @errorstested See JUnit test cases
 * @errorsgenerated See errata report
 * @author Travis Casper
 * @createdate 11/19/09
 * @modlog <p>
 *         <ul>
 *         Who/When/Why
 *         <li>Travis - 11/19 - Created
 *         <li>Travis - 11/24 - Made Some Minor Adjustments
 *         <li>Travis - 11/28 - Worked on Fixing Bugs
 *         <li>Travis - 11/29 - Worked on Adding Error Handlers
 *         <li>Travis - 11/29 - Added <code>symbolIsDefined</code> method
 *         </ul>
 *         <p>
 *         Coding Standards Met: "Signed Code Leader(Jaron)"
 *         <p>
 *         Testing Standards Met: "Signed Test Leader(Jamie)"
 */
public class Loader {
	private static class textRecord {
		public String address;
		public String macCode;
		public String relocationS1;
		public String relocationS2;
		public String relocationS3;
		public String symbolS1;
		public String symbolS2;
		public String symbolS3;
		public String operatorS1;
		public String operatorS2;
		public String operatorS3;
		public String moduleName;
		public int numOfOperands;
		public int moduleAdjustment;

		public textRecord(){

			address = "";
			macCode = "";
			relocationS1 = "";
			relocationS2 = "";
			relocationS3 = "";
			symbolS1 = "";
			symbolS2 = "";
			symbolS3 = "";
			operatorS1 = "";
			operatorS2 = "";
			operatorS3 = "";
			moduleName = "";
			numOfOperands = -1;
			moduleAdjustment = 0;

		}

	}

	private static List<textRecord> textRecordList;
	private static ErrorHandler2 errorHandler;
	private static int lineNumber;
	private static List<String> memoryArray;
	
	private Loader() {}

	/**
	 * @modulename initialize.
	 * @description This method initializes the Loader to its initial values.
	 * @callsequence <code>Loader.initialize();</code>
	 * @inparam none
	 * @outparam none
	 * @errorstested See JUnit test cases
	 * @errorsgenerated See errata report
	 * @author Travis Casper
	 * @createdate 11/19/09
	 * @modlog <p>
	 *         <ul>
	 *         Who/When/Why
	 *         <li>Travis - 11/19 - Created
	 *         </ul>
	 *         <p>
	 *         Coding Standards Met: "Signed Code Leader(Jaron)"
	 *         <p>
	 *         Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public static void initialize() {
		textRecordList = new ArrayList<textRecord>(0);
		memoryArray = new ArrayList<String>(0);
		lineNumber = 0;
	}

	/**
	 * @modulename addTextRecord
	 * @description This class represents the pass two of the Linker/Loader.
	 * Affectionately called the Loader, as it handles loading memory of the 
	 * combined programs
	 * @callsequence <code>Loader.addTextRecord(String address, String macCode, String relocationS1, String operatorS1, String symbolS1, String moduleName, int moduleAdjustment);</code>
	 * @inparam address - String that represents the address of the current Text Record<p>
	 * macCode - String that represents the incoming Machine Code of the current Text Record<p>
	 * relocationS1 - String that represents the S1 Relocation Code of the current Text Record<p>
	 * operatorS1 - String that represents the S1 Operator of the current Text Record<p>
	 * symbolS1 - String that represents the S1 Symbol of the current Text Record<p>
	 * moduleName - String that represents the module Name of the current Text Record<p>
	 * moduleAdjustment - Integer that represents the Module Adjustment of the current Text Record<p>
	 * @outparam none
	 * @errorstested See JUnit test cases
	 * @errorsgenerated See errata report
	 * @author Travis Casper
	 * @createdate 11/19/09
	 * @modlog <p>
	 *         <ul>
	 *         Who/When/Why
	 *         <li>Travis - 11/19 - Created
	 *         </ul>
	 *         <p>
	 *         Coding Standards Met: "Signed Code Leader(Jaron)"
	 *         <p>
	 *         Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public static void addTextRecord(String address, String macCode, String relocationS1, String operatorS1, String symbolS1, String moduleName, int moduleAdjustment) {
		textRecord tempRec = new textRecord();

		tempRec.address = address;
		tempRec.macCode = macCode;
		tempRec.relocationS1 = relocationS1;
		tempRec.operatorS1 = operatorS1;
		tempRec.symbolS1 = symbolS1;
		tempRec.relocationS2 = "";
		tempRec.operatorS2 = "";
		tempRec.symbolS2 = "";
		tempRec.relocationS3 = "";
		tempRec.operatorS3 = "";
		tempRec.symbolS3 = "";
		tempRec.moduleName = moduleName;
		tempRec.numOfOperands = 1;
		tempRec.moduleAdjustment = moduleAdjustment;

		textRecordList.add(tempRec);
	}

	/**
	 * @modulename addTextRecord
	 * @description This class represents the pass two of the Linker/Loader.
	 * Affectionately called the Loader, as it handles loading memory of the 
	 * combined programs
	 * @callsequence <code>Loader.addTextRecord(String address, String macCode, String relocationS1, String operatorS1, String symbolS1, String relocationS2, String operatorS2, String symbolS2, String moduleName, int moduleAdjustment);</code>
	 * @inparam address - String that represents the address of the current Text Record<p>
	 * macCode - String that represents the incoming Machine Code of the current Text Record<p>
	 * relocationS1 - String that represents the S1 Relocation Code of the current Text Record<p>
	 * operatorS1 - String that represents the S1 Operator of the current Text Record<p>
	 * symbolS1 - String that represents the S1 Symbol of the current Text Record<p>
	 * relocationS2 - String that represents the S2 Relocation Code of the current Text Record<p>
	 * operatorS2 - String that represents the S2 Operator of the current Text Record<p>
	 * symbolS2 - String that represents the S2 Symbol of the current Text Record<p>
	 * moduleName - String that represents the module Name of the current Text Record<p>
	 * moduleAdjustment - Integer that represents the Module Adjustment of the current Text Record<p>
	 * @outparam none
	 * @errorstested See JUnit test cases
	 * @errorsgenerated See errata report
	 * @author Travis Casper
	 * @createdate 11/19/09
	 * @modlog <p>
	 *         <ul>
	 *         Who/When/Why
	 *         <li>Travis - 11/19 - Created
	 *         </ul>
	 *         <p>
	 *         Coding Standards Met: "Signed Code Leader(Jaron)"
	 *         <p>
	 *         Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public static void addTextRecord(String address, String macCode, String relocationS1, String operatorS1, String symbolS1, String relocationS2, String operatorS2, String symbolS2, String moduleName, int moduleAdjustment) {
		textRecord tempRec = new textRecord();

		tempRec.address = address;
		tempRec.macCode = macCode;
		tempRec.relocationS1 = relocationS1;
		tempRec.operatorS1 = operatorS1;
		tempRec.symbolS1 = symbolS1;
		tempRec.relocationS2 = relocationS2;
		tempRec.operatorS2 = operatorS2;
		tempRec.symbolS2 = symbolS2;
		tempRec.relocationS3 = "";
		tempRec.operatorS3 = "";
		tempRec.symbolS3 = "";
		tempRec.moduleName = moduleName;
		tempRec.numOfOperands = 2;
		tempRec.moduleAdjustment = moduleAdjustment;

		textRecordList.add(tempRec);
	}

	/**
	 * @modulename addTextRecord
	 * @description This class represents the pass two of the Linker/Loader.
	 * Affectionately called the Loader, as it handles loading memory of the 
	 * combined programs
	 * @callsequence <code>Loader.addTextRecord(String address, String macCode, String relocationS1, String operatorS1, String symbolS1, String relocationS2, String operatorS2, String symbolS2, String relocationS3, String operatorS3, String symbolS3, String moduleName, int moduleAdjustment);</code>
	 * @inparam address - String that represents the address of the current Text Record<p>
	 * macCode - String that represents the incoming Machine Code of the current Text Record<p>
	 * relocationS1 - String that represents the S1 Relocation Code of the current Text Record<p>
	 * operatorS1 - String that represents the S1 Operator of the current Text Record<p>
	 * symbolS1 - String that represents the S1 Symbol of the current Text Record<p>
	 * relocationS2 - String that represents the S2 Relocation Code of the current Text Record<p>
	 * operatorS2 - String that represents the S2 Operator of the current Text Record<p>
	 * symbolS2 - String that represents the S2 Symbol of the current Text Record<p>
	 * relocationS3 - String that represents the S3 Relocation Code of the current Text Record<p>
	 * operatorS3 - String that represents the S3 Operator of the current Text Record<p>
	 * symbolS3 - String that represents the S3 Symbol of the current Text Record<p>
	 * moduleName - String that represents the module Name of the current Text Record<p>
	 * moduleAdjustment - Integer that represents the Module Adjustment of the current Text Record<p>
	 * @outparam none
	 * @errorstested See JUnit test cases
	 * @errorsgenerated See errata report
	 * @author Travis Casper
	 * @createdate 11/19/09
	 * @modlog <p>
	 *         <ul>
	 *         Who/When/Why
	 *         <li>Travis - 11/19 - Created
	 *         </ul>
	 *         <p>
	 *         Coding Standards Met: "Signed Code Leader(Jaron)"
	 *         <p>
	 *         Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public static void addTextRecord(String address, String macCode, String relocationS1, String operatorS1, String symbolS1, String relocationS2, String operatorS2, String symbolS2, String relocationS3, String operatorS3, String symbolS3, String moduleName, int moduleAdjustment) {
		textRecord tempRec = new textRecord();

		tempRec.address = address;
		tempRec.macCode = macCode;
		tempRec.relocationS1 = relocationS1;
		tempRec.operatorS1 = operatorS1;
		tempRec.symbolS1 = symbolS1;
		tempRec.relocationS2 = relocationS2;
		tempRec.operatorS2 = operatorS2;
		tempRec.symbolS2 = symbolS2;
		tempRec.relocationS3 = relocationS3;
		tempRec.operatorS3 = operatorS3;
		tempRec.symbolS3 = symbolS3;
		tempRec.moduleName = moduleName;
		tempRec.numOfOperands = 3;
		tempRec.moduleAdjustment = moduleAdjustment;

		textRecordList.add(tempRec);
	}

	/**
	 * @modulename runLoader.
	 * @description This method will format the Machine Code for each Text Record,
	 *  and add it to the LoadFile.
	 * @callsequence <code>Loader.runLoader();</code>
	 * @inparam none
	 * @outparam none
	 * @errorstested See JUnit test cases
	 * @errorsgenerated See errata report
	 * @author Travis Casper
	 * @createdate 11/19/09
	 * @modlog <p>
	 *         <ul>
	 *         Who/When/Why
	 *         <li>Travis - 11/19 - Created
	 *         <li>Travis - 11/21 - Made Some minor Adjustments
	 *         </ul>
	 *         <p>
	 *         Coding Standards Met: "Signed Code Leader(Jaron)"
	 *         <p>
	 *         Testing Standards Met: "Signed Test Leader(Jamie)"
	 */
	public static void runLoader() {
		errorHandler = Linker.textErrors;
		for (textRecord tRec : textRecordList) {
			System.out.println(tRec.address);
			System.out.println(tRec.macCode);
			System.out.println(tRec.moduleName);
			System.out.println(tRec.relocationS1);
			System.out.println(tRec.operatorS1);
			System.out.println(tRec.symbolS1);
			System.out.println(tRec.relocationS2);
			System.out.println(tRec.operatorS2);
			System.out.println(tRec.symbolS2);
			System.out.println(tRec.relocationS3);
			System.out.println(tRec.operatorS3);
			System.out.println(tRec.symbolS3);
			Integer address = Integer.parseInt(tRec.address);
			String macCode = formatMachineCode(tRec);
			tRec.macCode = macCode;
			memoryArray.add(macCode);
			LoadFile.addTextRecord(address, macCode, tRec.moduleName);
			lineNumber++;
		}
		dumpMemory();
	}

	private static String formatMachineCode(textRecord record) {
		String lineNumberStr = Integer.toString(lineNumber);
		boolean makeAdjustment = false;
		String begCode = parseBeginning(record);
		String adjustedAddressStr = "";
		String adjustedHexCode = "";
		Integer adjustedAddress = 0;
		int oLength = record.numOfOperands;
		if (oLength == 1) { 
			if (record.relocationS1.equalsIgnoreCase("R")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS1);
					if (record.operatorS1.equalsIgnoreCase("\u002b")) {
						adjustedAddress = symbolValue + record.moduleAdjustment;
						makeAdjustment = true;
					} else if (record.operatorS1.equalsIgnoreCase("\u002d")) {
						//ERROR: Invalid Operator for Relative Addressing
						errorHandler.addToErrorList(lineNumberStr, "1", "When Using Only One Operand, Relative Relocation cannot use a Negative Operator");
					}
				} catch (NumberFormatException e) {
					//ERROR: Relative symbol is not a number
					errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Relative Relocation.");
				}

			} else if (record.relocationS1.equalsIgnoreCase("C")) {
				if (LoadMap.symbolIsDefined(record.symbolS1)) {
					String extAddrStr = LoadMap.returnLinkerLocation(record.symbolS1);
					Integer extAddr = Integer.parseInt(extAddrStr, 16);
					extAddr = extAddr + record.moduleAdjustment;
					if (record.operatorS1.equalsIgnoreCase("\u002b")) {
						adjustedAddress = extAddr + record.moduleAdjustment;
						makeAdjustment = true;
					} else if (record.operatorS1.equalsIgnoreCase("\u002d")) {
						//ERROR: Invalid Operator for Complex Addressing
						errorHandler.addToErrorList(lineNumberStr, "1", "When Using Only One Operand, Complex Relocation cannot use a Negative Operator");
					}
				} else {
					//ERROR: External Symbol Not Defined.
					errorHandler.addToErrorList(lineNumberStr, "12", "The External Symbol " + record.symbolS1 + " has not been defined.");
				}
			} else if (record.relocationS1.equalsIgnoreCase("B") || record.relocationS1.equalsIgnoreCase("A")) {
				try{
					Integer.parseInt(record.symbolS1);
				} catch (NumberFormatException e) {
					//ERROR: Absolute or Base Relative symbol is not a number
					if (record.relocationS1.equalsIgnoreCase("B")) {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Base Relative Relocation.");
					} else {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Absolute Relocation.");
					}
				}
			}
		} else if (oLength == 2) {
			int s1 = 0;
			int s2 = 0;
			if (record.relocationS1.equalsIgnoreCase("R")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS1);
					s1 = symbolValue + record.moduleAdjustment;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					//ERROR: Relative symbol is not a number
					errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Relative Relocation.");
				}
			} else if (record.relocationS1.equalsIgnoreCase("C")) {
				if (LoadMap.symbolIsDefined(record.symbolS1)) {
					String extAddrStr = LoadMap.returnLinkerLocation(record.symbolS1);
					Integer extAddr = Integer.parseInt(extAddrStr, 16);
					s1 = extAddr;
					makeAdjustment = true;
				} else {
					//ERROR: External Symbol Not Defined.
					errorHandler.addToErrorList(lineNumberStr, "12", "The External Symbol " + record.symbolS1 + " has not been defined.");
				}
			} else if (record.relocationS1.equalsIgnoreCase("B") || record.relocationS1.equalsIgnoreCase("A")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS1);
					s1 = symbolValue;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					//ERROR: Absolute or Base Relative symbol is not a number
					if (record.relocationS1.equalsIgnoreCase("B")) {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Base Relative Relocation.");
					} else {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Absolute Relocation.");
					}
				}
			}
			if (record.relocationS2.equalsIgnoreCase("R")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS2);
					s2 = symbolValue + record.moduleAdjustment;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					//ERROR: Relative symbol is not a number
					errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS2 + " is not a Number, which is invalid for Relative Relocation.");
				}
			} else if (record.relocationS2.equalsIgnoreCase("C")) {
				if (LoadMap.symbolIsDefined(record.symbolS2)) {
					String extAddrStr = LoadMap.returnLinkerLocation(record.symbolS2);
					Integer extAddr = Integer.parseInt(extAddrStr, 16);
					s2 = extAddr;
					makeAdjustment = true;
				} else {
					//ERROR: External Symbol Not Defined.
					errorHandler.addToErrorList(lineNumberStr, "12", "The External Symbol " + record.symbolS2 + " has not been defined.");
				}
			} else if (record.relocationS2.equalsIgnoreCase("B") || record.relocationS2.equalsIgnoreCase("A")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS2);
					s2 = symbolValue;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					//ERROR: Absolute or Base Relative symbol is not a number
					if (record.relocationS2.equalsIgnoreCase("B")) {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS2 + " is not a Number, which is invalid for Base Relative Relocation.");
					} else {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS2 + " is not a Number, which is invalid for Absolute Relocation.");
					}
				}
			}
			if (record.operatorS1.equalsIgnoreCase("\u002b") && record.operatorS2.equalsIgnoreCase("\u002b")) {
				adjustedAddress = s1 + s2;
			} else if (record.operatorS1.equalsIgnoreCase("\u002b") && record.operatorS2.equalsIgnoreCase("\u002d")) {
				adjustedAddress = s1 - s2;
			} else if (record.operatorS1.equalsIgnoreCase("\u002d") && record.operatorS2.equalsIgnoreCase("\u002b")) {
				adjustedAddress = -s1 + s2;
			} else if (record.operatorS1.equalsIgnoreCase("\u002d") && record.operatorS2.equalsIgnoreCase("\u002d")) {
				adjustedAddress = s1 - s2;
			}
		} else if (oLength == 3) {

			int s1 = 0;
			int s2 = 0;
			int s3 = 0;
			if (record.relocationS1.equalsIgnoreCase("R")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS1);
					s1 = symbolValue + record.moduleAdjustment;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					//ERROR: Relative symbol is not a number
					errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Relative Relocation.");
				}
			} else if (record.relocationS1.equalsIgnoreCase("C")) {
				if (LoadMap.symbolIsDefined(record.symbolS1)) {
					String extAddrStr = LoadMap.returnLinkerLocation(record.symbolS1);
					Integer extAddr = Integer.parseInt(extAddrStr, 16);
					s1 = extAddr;
					makeAdjustment = true;
				} else {
					//ERROR: External Symbol Not Defined.
					errorHandler.addToErrorList(lineNumberStr, "12", "The External Symbol " + record.symbolS1 + " has not been defined.");
				}
			} else if (record.relocationS1.equalsIgnoreCase("B") || record.relocationS1.equalsIgnoreCase("A")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS1);
					s1 = symbolValue;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					// ERROR: Absolute or Base Relative symbol is not a number
					if (record.relocationS1.equalsIgnoreCase("B")) {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Base Relative Relocation.");
					} else {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS1 + " is not a Number, which is invalid for Absolute Relocation.");
					}
				}
			}
			if (record.relocationS2.equalsIgnoreCase("R")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS2);
					s2 = symbolValue + record.moduleAdjustment;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					// ERROR: Relative symbol is not a number
					errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS2 + " is not a Number, which is invalid for Relative Relocation.");
				}
			} else if (record.relocationS2.equalsIgnoreCase("C")) {
				if (LoadMap.symbolIsDefined(record.symbolS2)) {
					String extAddrStr = LoadMap.returnLinkerLocation(record.symbolS2);
					Integer extAddr = Integer.parseInt(extAddrStr, 16);
					s2 = extAddr;
					makeAdjustment = true;
				} else {
					// ERROR: External Symbol Not Defined.
					errorHandler.addToErrorList(lineNumberStr, "12", "The External Symbol " + record.symbolS2 + " has not been defined.");
				}
			} else if (record.relocationS2.equalsIgnoreCase("B") || record.relocationS2.equalsIgnoreCase("A")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS2);
					s2 = symbolValue;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					// ERROR: Absolute or Base Relative symbol is not a number
					if (record.relocationS2.equalsIgnoreCase("B")) {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS2 + " is not a Number, which is invalid for Base Relative Relocation.");
					} else {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS2 + " is not a Number, which is invalid for Absolute Relocation.");
					}
				}
			}
			if (record.relocationS3.equalsIgnoreCase("R")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS3);
					s3 = symbolValue + record.moduleAdjustment;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					//ERROR: Relative symbol is not a number
					errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS3 + " is not a Number, which is invalid for Relative Relocation.");
				}
			} else if (record.relocationS3.equalsIgnoreCase("C")) {
				if (LoadMap.symbolIsDefined(record.symbolS3)) {
					String extAddrStr = LoadMap.returnLinkerLocation(record.symbolS3);
					Integer extAddr = Integer.parseInt(extAddrStr, 16);
					s3 = extAddr;
					makeAdjustment = true;
				} else {
					//ERROR: External Symbol Not Defined.
					errorHandler.addToErrorList(lineNumberStr, "12", "The External Symbol " + record.symbolS3 + " has not been defined.");
				}
			} else if (record.relocationS3.equalsIgnoreCase("B") || record.relocationS3.equalsIgnoreCase("A")) {
				try{
					int symbolValue = Integer.parseInt(record.symbolS3);
					s3 = symbolValue;
					makeAdjustment = true;
				} catch (NumberFormatException e) {
					// ERROR: Absolute or Base Relative symbol is not a number
					if (record.relocationS3.equalsIgnoreCase("B")) {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS3 + " is not a Number, which is invalid for Base Relative Relocation.");
					} else {
						errorHandler.addToErrorList(lineNumberStr, "11", record.symbolS3 + " is not a Number, which is invalid for Absolute Relocation.");
					}
				}
			}
			if (record.operatorS1.equalsIgnoreCase("\u002b") && record.operatorS2.equalsIgnoreCase("\u002b") && record.operatorS3.equalsIgnoreCase("\u002b")) {
				adjustedAddress = s1 + s2 + s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002b") && record.operatorS2.equalsIgnoreCase("\u002b") && record.operatorS3.equalsIgnoreCase("\u002d")) {
				adjustedAddress = s1 + s2 - s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002b") && record.operatorS2.equalsIgnoreCase("\u002d") && record.operatorS3.equalsIgnoreCase("\u002d")) {
				adjustedAddress = s1 - s2 - s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002b") && record.operatorS2.equalsIgnoreCase("\u002d") && record.operatorS3.equalsIgnoreCase("\u002b")) {
				adjustedAddress = s1 - s2 + s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002d") && record.operatorS2.equalsIgnoreCase("\u002b") && record.operatorS3.equalsIgnoreCase("\u002b")) {
				adjustedAddress = -s1 + s2 + s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002d") && record.operatorS2.equalsIgnoreCase("\u002b") && record.operatorS3.equalsIgnoreCase("\u002d")) {
				adjustedAddress = -s1 + s2 - s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002d") && record.operatorS2.equalsIgnoreCase("\u002d") && record.operatorS3.equalsIgnoreCase("\u002d")) {
				adjustedAddress = -s1 - s2 - s3;
			} else if (record.operatorS1.equalsIgnoreCase("\u002d") && record.operatorS2.equalsIgnoreCase("\u002d") && record.operatorS3.equalsIgnoreCase("\u002b")) {
				adjustedAddress = -s1 - s2 + s3;
			}
		}

		if (adjustedAddress < 0) {
			//ERROR: Computed Address is negative
			errorHandler.addToErrorList(lineNumberStr, "10", "The Computed Address " + adjustedAddress.toString() + " is Negative.");
			makeAdjustment = false;
		} else if (adjustedAddress > 2048) {
			//ERROR: Computed Address is too big
			errorHandler.addToErrorList(lineNumberStr, "10", "The Computed Address " + adjustedAddress.toString() + " is too Large to fit in the Address Field.");
			makeAdjustment = false;
		}

		if (makeAdjustment) {
			adjustedAddressStr = Integer.toBinaryString(adjustedAddress);
			while (adjustedAddressStr.length() < 11) {
				adjustedAddressStr = "0" + adjustedAddressStr;
			}
			while (adjustedAddressStr.length() > 11) {
				adjustedAddressStr = adjustedAddressStr.substring(1);
			}
			String adjustedBinCode = begCode + adjustedAddressStr;
			int n = 0;
			while (n < 24) {
				String halfWord = adjustedBinCode.substring(n, n + 4);
				adjustedHexCode =  adjustedHexCode + Convertor.binaryToHex(halfWord);
				n+=4;
			}
			return adjustedHexCode;
		} else {
			return record.macCode;
		}
	}

	private static String parseBeginning(textRecord record) {
		char[] codeArray = record.macCode.toCharArray();
		StringBuilder convertedCode = new StringBuilder();
		for (char h : codeArray) {
			convertedCode.append(Convertor.hexToBinary(h));
		}
		String code = convertedCode.toString();
		if(code.length()>11){
		String begCode = code.substring(0, code.length() - 11);
		return begCode;
		}
	return "000000000000000000000000";
	}

	private static void dumpMemory() {
		Main2.appendDebugText("\n\t\t...Memory Dump...\n");
		while (memoryArray.size() < 4096) {
			memoryArray.add("A80063");
		}
		for (int i = 0; i < memoryArray.size(); i = i + 8) {
			StringBuilder debugText = new StringBuilder();
			if (i > 15) {
				if (i > 255) {
					debugText.append("memoryArray[" + Integer.toHexString(i).toUpperCase());
				} else {
					debugText.append("memoryArray[0" + Integer.toHexString(i).toUpperCase());
				}
			} else {
				debugText.append("memoryArray[00" + Integer.toHexString(i).toUpperCase());
			}
			if ((i + 7) > 15) {
				if ((i + 7) > 255) {
					debugText.append("-" + Integer.toHexString(i + 7).toUpperCase() + "]:\t");
				} else {
					debugText.append("-0" + Integer.toHexString(i + 7).toUpperCase() + "]:\t");
				}
			} else {
				debugText.append("-00" + Integer.toHexString(i + 7).toUpperCase() + "]:\t");
			}
			debugText.append(memoryArray.get(i) + "\t" + memoryArray.get(i + 1) + "\t" + memoryArray.get(i + 2)
					+ "\t" + memoryArray.get(i + 3) + "\t" + memoryArray.get(i + 4) + "\t"
					+ memoryArray.get(i + 5) + "\t" + memoryArray.get(i + 6) + "\t"
					+ memoryArray.get(i + 7));
			Main2.appendDebugText(debugText.toString());
		}
		Main2.appendDebugText(Main.newline);
	}

}
